{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Rate of Change\n",
    "Functions are often visualized as a line on a graph, and this line shows how the value returned by the function changes based on changes in the input value.\n",
    "\n",
    "## Linear Rate of Change\n",
    "\n",
    "For example, imagine a function that returns the number of meters travelled by a cyclist based on the number of seconds that the cyclist has been cycling.\n",
    "\n",
    "Here is such a function:\n",
    "\n",
    "\\begin{equation}q(x) = 2x + 1\\end{equation}\n",
    "\n",
    "We can plot the output for this function for a period of 10 seconds like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "def q(x):\n",
    "    return 2*x + 1\n",
    "\n",
    "# Plot the function\n",
    "import numpy as np\n",
    "from matplotlib import pyplot as plt\n",
    "\n",
    "# Create an array of x values from 0 to 10\n",
    "x = np.array(range(0, 11))\n",
    "\n",
    "# Set up the graph\n",
    "plt.xlabel('Seconds')\n",
    "plt.ylabel('Meters')\n",
    "plt.xticks(range(0,11, 1))\n",
    "plt.yticks(range(0, 22, 1))\n",
    "plt.grid()\n",
    "\n",
    "# Plot x against q(x)\n",
    "plt.plot(x,q(x), color='green')\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It's clear from the graph that ***q*** is a *linear* function that describes a slope in which distance increases at a constant rate over time. In other words, the cyclist is travelling at a constant speed.\n",
    "\n",
    "But what speed?\n",
    "\n",
    "Speed, or more technically, velocity is a measure of change - it measures how the distance travelled changes over time (which is why we typically express it as a unit of distance per a unit of time, like *miles-per-hour* or *meters-per-second*). So we're looking for a way to measure the change in the line created by the function.\n",
    "\n",
    "The change in values along the line define its *slope*, which we know from a previous lesson is represented like this:\n",
    "\n",
    "\\begin{equation}m = \\frac{\\Delta{y}}{\\Delta{x}} \\end{equation}\n",
    "\n",
    "We can calculate the slope of our function like this:\n",
    "\n",
    "\\begin{equation}m = \\frac{q(x)_{2} - q(x)_{1}}{x_{2} - x_{1}} \\end{equation}\n",
    "\n",
    "So we just need two ordered pairs of ***x*** and ***q(x)*** values from our line to apply this equation.\n",
    "\n",
    "- After 1 second, ***x*** is 1 and ***q***(1) = **3**.\n",
    "- After 10 seconds, ***x*** is 10 and ***q***(10) = 21.\n",
    "\n",
    "So we can meassure the rate of change like this:\n",
    "\n",
    "\\begin{equation}m = \\frac{21 - 3}{10 - 1} \\end{equation}\n",
    "\n",
    "This is the same as:\n",
    "\n",
    "\\begin{equation}m = \\frac{18}{9} \\end{equation}\n",
    "\n",
    "Which simplifies to:\n",
    "\n",
    "\\begin{equation}m = \\frac{2}{1} \\end{equation}\n",
    "\n",
    "So our rate of change is <sup>2</sup>/<sub>1</sub> or put another way, the cyclist is travelling at 2 meters-per-second."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Average Rate of Change\n",
    "OK, let's look at another function that calculates distance travelled for a given number of seconds:\n",
    "\n",
    "\\begin{equation}r(x) = x^{2} + x\\end{equation}\n",
    "\n",
    "Let's take a look at that using Python:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "def r(x):\n",
    "    return x**2 + x\n",
    "\n",
    "# Plot the function\n",
    "import numpy as np\n",
    "from matplotlib import pyplot as plt\n",
    "\n",
    "# Create an array of x values from 0 to 10\n",
    "x = np.array(range(0, 11))\n",
    "\n",
    "# Set up the graph\n",
    "plt.xlabel('Seconds')\n",
    "plt.ylabel('Meters')\n",
    "plt.grid()\n",
    "\n",
    "# Plot x against r(x)\n",
    "plt.plot(x,r(x), color='green')\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This time, the function is not linear. It's actually a quadratic function, and the line from 0 seconds to 10 seconds shows an exponential increase; in other words, the cyclist is *accelerating*.\n",
    "\n",
    "Technically, acceleration itself is a measure of change in velocity over time; and velocity, as we've already discussed, is a measure of change in distance over time. So measuring accelleration is pretty complex, and requires *differential calculus*, which we're going to cover shortly. In fact, even just measuring the velocity at a single point in time requires differential calculus; but we can use algebraic methods to calculate an *average* rate of velocity for a given period shown in the graph.\n",
    "\n",
    "First, we need to define a *secant* line that joins two points in our exponential arc to create a straight slope. For example, a secant line for the entire 10 second time span would join the following two points:\n",
    "\n",
    "- 0, ***r***(0)\n",
    "- 10, ***r***(10)\n",
    "\n",
    "Run the following Python code to visualize this line:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "def r(x):\n",
    "    return (x)**2 + x\n",
    "\n",
    "# Plot the function\n",
    "import numpy as np\n",
    "from matplotlib import pyplot as plt\n",
    "\n",
    "# Create an array of x values from 0 to 10\n",
    "x = np.array(range(0, 11))\n",
    "\n",
    "# Create an array for the secant line\n",
    "s = np.array([0,10])\n",
    "\n",
    "# Set up the graph\n",
    "plt.xlabel('Seconds')\n",
    "plt.ylabel('Meters')\n",
    "plt.grid()\n",
    "\n",
    "# Plot x against r(x)\n",
    "plt.plot(x,r(x), color='green')\n",
    "\n",
    "# Plot the secant line\n",
    "plt.plot(s,r(s), color='magenta')\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, because the secant line is straight, we can apply the slope formula we used for a linear function to calculate the average velocity for the 10 second period:\n",
    "\n",
    "- At 0 seconds, ***x*** is 0 and ***r***(0) = **0**.\n",
    "- At 10 seconds, ***x*** is 10 and ***r***(10) = 110.\n",
    "\n",
    "So we can meassure the rate of change like this:\n",
    "\n",
    "\\begin{equation}m = \\frac{110 - 0}{10 - 0} \\end{equation}\n",
    "\n",
    "This is the same as:\n",
    "\n",
    "\\begin{equation}m = \\frac{110}{10} \\end{equation}\n",
    "\n",
    "Which simplifies to:\n",
    "\n",
    "\\begin{equation}m = \\frac{11}{1} \\end{equation}\n",
    "\n",
    "So our rate of change is <sup>11</sup>/<sub>1</sub> or put another way, the cyclist is travelling at an average velocity of 11 meters-per-second over the 10-second period.\n",
    "\n",
    "Of course, we can measure the average velocity between any two points on the exponential line. Use the following Python code to show the secant line for the period between 2 and 7 seconds, and calculate the average velocity for that period"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "def r(x):\n",
    "    return x**2 + x\n",
    "\n",
    "# Plot the function\n",
    "import numpy as np\n",
    "from matplotlib import pyplot as plt\n",
    "\n",
    "# Create an array of x values from 0 to 10\n",
    "x = np.array(range(0, 11))\n",
    "\n",
    "# Create an array for the secant line\n",
    "s = np.array([2,7])\n",
    "\n",
    "# Calculate rate of change\n",
    "x1 = s[0]\n",
    "x2 = s[-1]\n",
    "y1 = r(x1)\n",
    "y2 = r(x2)\n",
    "a = (y2 - y1)/(x2 - x1)\n",
    "\n",
    "\n",
    "# Set up the graph\n",
    "plt.xlabel('Seconds')\n",
    "plt.ylabel('Meters')\n",
    "plt.grid()\n",
    "\n",
    "# Plot x against r(x)\n",
    "plt.plot(x,r(x), color='green')\n",
    "\n",
    "# Plot the secant line\n",
    "plt.plot(s,r(s), color='magenta')\n",
    "\n",
    "plt.annotate('Average Velocity =' + str(a) + ' m/s',((x2+x1)/2, (y2+y1)/2))\n",
    "\n",
    "plt.show()\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.6",
   "language": "python",
   "name": "python36"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
